home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / msysjour / vol06 / 01 / kermit / wnterm.c < prev    next >
C/C++ Source or Header  |  1990-12-31  |  7KB  |  277 lines

  1. /* 
  2.  * WNTERM Main Module
  3.  *
  4.  * Copyright (c) 1990 by
  5.  * William S. Hall
  6.  * 3665 Benton Street, #66
  7.  * Santa Clara, CA 95051
  8. */
  9.  
  10. #define NOKANJI
  11. #define NOATOM
  12. #define NOSOUND
  13. #define NOMINMAX
  14. #include <windows.h>
  15. #include <limits.h>
  16. #include <string.h>
  17. #include <ascii.h>
  18. #include <stdlib.h>
  19. #include "ttycls.h"
  20.  
  21. /* Turn declarations in header file into defintions */
  22. #define EXTERN
  23. #include "wnterm.h"
  24.  
  25. /* Kermit information */
  26. #if defined(KERMIT)
  27. #define KERMITEXTERN
  28. #include "wnkerm.h"
  29. #endif
  30.  
  31. /* program entry point */
  32. int FAR PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, 
  33.                LPSTR lpszCmdLine, int cmdShow)
  34. {
  35.  
  36.     MSG msg;
  37.     
  38.   /* initialize program */
  39.     if (!InitProgram(hInstance,hPrevInstance, lpszCmdLine, cmdShow))
  40.     return FALSE;
  41.  
  42.   /* stay in this loop until window is destroyed */
  43.     while (TRUE) {
  44.         if (PeekMessage((LPMSG)&msg,NULL,0,0,PM_REMOVE)) {
  45.         if (msg.message == WM_QUIT)
  46.         break;
  47.         TranslateMessage((LPMSG)&msg);
  48.         DispatchMessage((LPMSG)&msg);
  49.     }
  50.     else {        /* Poll the communications loop */
  51.         if (LineState == IDM_ONLINE) {
  52.             if (ProcessComm()
  53. #if defined(KERMIT)
  54.             || Kermit.InTransfer
  55. #endif
  56.            )
  57.         PostMessage(MWnd.hWnd, WM_USER, Buflen, 0L);
  58.         }
  59.     }
  60.     }
  61.     return (int)msg.wParam;    // terminate program.
  62. }
  63.  
  64. /* Main window procedure */
  65. long FAR PASCAL MainWndProc(HWND hWnd,unsigned message,WORD wParam,LONG lParam)
  66. {
  67.  
  68.     // get our data structure for the window.
  69.     PTTYWND pMWnd = (PTTYWND)GetWindowWord(hWnd,0); 
  70.     PAINTSTRUCT ps;
  71.     register int i;
  72.  
  73.     switch(message) {
  74.  
  75. #if defined(KERMIT)
  76.     case WM_QUERYDRAGICON:
  77.         return MAKELONG(krmIcon, 0);
  78. #endif
  79.  
  80.       // control scrolling with this key.
  81.     case WM_KEYDOWN:
  82.         if (wParam == VK_SCROLL)
  83.             ScrollLock = GetKeyState(VK_SCROLL) & 1;
  84.         break;
  85.  
  86.       // process menu command.
  87.     case WM_COMMAND:
  88. #if defined(KERMIT)
  89.         if (krmWndCommand(hWnd, wParam))
  90.         break;
  91. #endif
  92.         WndCommand(hWnd, wParam, lParam);
  93.         break;
  94.  
  95.     /* 
  96.        When a character is received, and send it to tty display procedure.
  97.        This is the action when terminal is off-line
  98.     */
  99.     case WM_CHAR:
  100.         HideCaret(hWnd);
  101.       // the loop is a crude way to handle repeat characters
  102.         for (i = 0; i < (int)LOWORD(lParam); i++)
  103.             TTYDisplay(pMWnd, (short)1, (BYTE *)&wParam);
  104.         SetCaretPos(pMWnd->Pos.x, pMWnd->Pos.y);
  105.         ShowCaret(hWnd);
  106.         break;
  107.  
  108.       // recreate caret and reset its position
  109.         case WM_SIZE:
  110.         pMWnd->Width = LOWORD(lParam);
  111.         pMWnd->Height = HIWORD(lParam);
  112.         pMWnd->Pos.y = pMWnd->Height - pMWnd->CHeight - 1; 
  113.         if (hWnd == GetFocus()) {
  114.             CreateCaret(hWnd, (HBITMAP)NULL,2,pMWnd->CHeight);
  115.             SetCaretPos(pMWnd->Pos.x, pMWnd->Pos.y);
  116.             ShowCaret(hWnd);
  117.         }
  118.         break;
  119.  
  120.       // window has focus, so window can create a caret.
  121.     case WM_SETFOCUS:
  122.         CreateCaret(hWnd, (HBITMAP)NULL,2,pMWnd->CHeight);
  123.         SetCaretPos(pMWnd->Pos.x, pMWnd->Pos.y);
  124.         if (!IsIconic(hWnd))
  125.             ShowCaret(hWnd);
  126.         break;
  127.  
  128.       // window has lost focus, so window must kill the caret.
  129.     case WM_KILLFOCUS:
  130.         HideCaret(hWnd);
  131.         DestroyCaret();
  132.         break;
  133.  
  134.       // main window now exists so do some initialization.
  135.     case WM_CREATE:
  136.         WndCreate(hWnd,(LPCREATESTRUCT)lParam);
  137. #if defined(KERMIT)
  138.         if (!krmInit(hWnd, Buffer, &Buflen, &cid))
  139.         PostMessage(MWnd.hWnd, WM_SYSCOMMAND, SC_CLOSE, 0L);
  140. #endif
  141.         break;
  142.  
  143.       // have to close comm port if open before killing window.
  144.     case WM_CLOSE:
  145. #if defined(KERMIT)
  146.         if (krmShutdown() != IDYES)
  147.             break;
  148. #endif
  149.         if (cid >= 0) {
  150.         CloseComm(cid);
  151.         cid = INT_MIN;
  152.         }
  153.         if (smallfont)
  154.         DeleteObject(hfont);
  155.         DestroyWindow(hWnd);
  156.         break;
  157.  
  158.     case WM_QUERYENDSESSION:
  159. #if defined(KERMIT)
  160.         if (krmShutdown() != IDYES)
  161.             break;
  162. #endif
  163.         return ((LONG)TRUE);
  164.  
  165.       // This application is being destroyed by Windows exec.
  166.     case WM_ENDSESSION:
  167.         if (wParam)        // if true, close the comm port.
  168.         if (cid >= 0) {
  169.             CloseComm(cid);
  170.             cid = INT_MIN;
  171.         }
  172.         if (smallfont)
  173.         DeleteObject(hfont);
  174.         break;
  175.  
  176.       // tell program to exit.
  177.     case WM_DESTROY:
  178.         PostQuitMessage(0);
  179.         break;
  180.  
  181.       // if iconic, paint the icon window, otherwise redraw text buffer.
  182.     case WM_PAINT:
  183.         BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
  184. #if defined(KERMIT)
  185.         if (IsIconic(hWnd)) {
  186.         if (Kermit.InTransfer)
  187.             krmPaint(hWnd, ps.hdc);
  188.         else {
  189.             RECT rect;
  190.             GetClientRect(hWnd, &rect);
  191.             DrawIcon(ps.hdc, 
  192.                  (rect.right - GetSystemMetrics(SM_CXICON)) / 2,
  193.                  (rect.bottom - GetSystemMetrics(SM_CYICON)) / 2,
  194.                  krmIcon);
  195.         }
  196.         }
  197.         else
  198. #endif        
  199.              MainWndPaint(hWnd, (LPPAINTSTRUCT)&ps);
  200.         EndPaint(hWnd, (LPPAINTSTRUCT)&ps);
  201.         break;
  202.  
  203.       // all other messages go through here.
  204.     default:
  205.         return ((long)DefWindowProc(hWnd,message,wParam,lParam));
  206.     }
  207.     return(0L);    /* this means we processed the message */
  208. }
  209.  
  210. /* 
  211.  * Subclass window procedure.  When we are on-line, all window 
  212.  *  messages come here first
  213.  */
  214. LONG FAR PASCAL MainWndSubProc(HWND hWnd, unsigned message,
  215.                    WORD wParam, LONG lParam)
  216. {
  217.  
  218.     PTTYWND pMWnd = (PTTYWND)GetWindowWord(hWnd,0);
  219.     register int i;
  220.  
  221.   // we are only interested in these messages.
  222.     switch(message) {
  223.  
  224.       // buffer from comm port has been posted to us.
  225.     case WM_USER:
  226. #if defined(KERMIT)
  227.         if (Kermit.InTransfer) {
  228.         wart();
  229.             break;
  230.         }
  231. #endif
  232.         if ((Buflen) && !IsIconic(MWnd.hWnd)) {
  233.             HideCaret(hWnd);
  234.             Buflen = TTYDisplay(pMWnd, (short)wParam, Buffer);
  235.             SetCaretPos(pMWnd->Pos.x, pMWnd->Pos.y);
  236.             ShowCaret(hWnd);
  237.         }
  238.         break;
  239.  
  240.       // transmit key from keyboard.  Loop is crude way to handle repeat chars.
  241.     case WM_CHAR:
  242.         for (i = 0; i < (int)LOWORD(lParam); i++)
  243.             WriteComm(cid, (LPSTR)&wParam,1);
  244.         if (!MWnd.LocalEcho)    // if no local echo, then done
  245.         break;
  246.  
  247.     // all other messages must go thru normal channels.
  248.     default:
  249.         return(CallWindowProc(fpMainWndProc,hWnd,message,wParam,lParam));
  250.     }
  251.     return(0L);
  252. }
  253.  
  254. /* come here to read the communications buffer if no messages to process */
  255. int NEAR ProcessComm(void)
  256. {
  257.  
  258.     COMSTAT ComStatus;
  259.     static int OldBuflen;
  260.     register int result = 0;
  261.     register WORD room = BUFSIZE - Buflen;    // check for space
  262.  
  263.   // if anything left over, move it to front.
  264.     if ((Buflen > 0) && (Buflen < OldBuflen))
  265.     memmove(Buffer, Buffer + OldBuflen - Buflen, Buflen);
  266.  
  267.     if (room > 0) {
  268.     if (GetCommError(cid, (COMSTAT FAR *)&ComStatus) == 0) {
  269.             if (ComStatus.cbInQue) {
  270.             result = ReadComm(cid,Buffer+Buflen,min(ComStatus.cbInQue,room));
  271.         OldBuflen = Buflen += abs(result);
  272.         }
  273.     }
  274.     }
  275.     return Buflen;
  276. }
  277.